/**
 * Axios HTTP Client Configuration
 *
 * 配置Axios实例,包含:
 * - 基础URL配置
 * - 请求/响应拦截器
 * - 错误处理
 * - 认证token管理
 */

import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import type { ApiResponse } from '../models/types'

/**
 * 创建Axios实例
 */
const client = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
})

/**
 * 请求拦截器
 * - 添加认证token
 * - 添加请求时间戳
 * - 日志记录
 */
client.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // TODO: 添加认证token (如果实现了认证系统)
    // const token = localStorage.getItem('auth_token')
    // if (token && config.headers) {
    //   config.headers.Authorization = `Bearer ${token}`
    // }

    // 添加请求时间戳 (用于性能监控)
    if (config.headers) {
      config.headers['X-Request-Time'] = Date.now().toString()
    }

    // 开发环境日志
    if (import.meta.env.DEV) {
      console.log('[API Request]', {
        method: config.method?.toUpperCase(),
        url: config.url,
        params: config.params,
        data: config.data,
      })
    }

    return config as any
  },
  (error: AxiosError) => {
    console.error('[API Request Error]', error)
    return Promise.reject(error)
  }
)

/**
 * 响应拦截器
 * - 统一响应格式处理
 * - 错误处理
 * - 性能监控
 */
client.interceptors.response.use(
  (response: AxiosResponse<any>) => {
    // 计算请求耗时
    const requestTime = response.config.headers?.['X-Request-Time']
    if (requestTime && import.meta.env.DEV) {
      const duration = Date.now() - parseInt(requestTime as string, 10)
      console.log('[API Response]', {
        url: response.config.url,
        status: response.status,
        duration: `${duration}ms`,
        data: response.data,
      })
    }

    // 处理204 No Content - 没有响应体
    if (response.status === 204) {
      response.data = {
        success: true,
        message: '操作成功',
      } as ApiResponse<any>
      return response
    }

    // 自动包装非ApiResponse格式的响应
    // 如果响应没有success字段,说明是直接的业务对象(如Spring Page),需要包装
    if (response.data && typeof response.data === 'object' && !('success' in response.data)) {
      const wrappedData: ApiResponse<any> = {
        success: true,
        data: response.data,
      }
      response.data = wrappedData
    }

    // 返回包装后的响应
    return response
  },
  (error: AxiosError<ApiResponse<any>>) => {
    // 错误处理
    const errorResponse: ApiResponse<any> = {
      success: false,
      message: '请求失败',
    }

    if (error.response) {
      // 服务器返回错误响应
      const { status, data } = error.response

      switch (status) {
        case 400:
          errorResponse.message = data?.message || '请求参数错误'
          break
        case 401:
          errorResponse.message = '未授权,请登录'
          // TODO: 跳转到登录页
          break
        case 403:
          errorResponse.message = '无权限访问'
          break
        case 404:
          errorResponse.message = data?.message || '资源不存在'
          break
        case 500:
          errorResponse.message = data?.message || '服务器内部错误'
          break
        case 503:
          errorResponse.message = '服务暂时不可用'
          break
        default:
          errorResponse.message = data?.message || `请求失败 (${status})`
      }

      errorResponse.error = data?.error
    } else if (error.request) {
      // 请求已发送但没有收到响应
      errorResponse.message = '网络连接失败,请检查网络'
    } else {
      // 请求配置出错
      errorResponse.message = error.message || '请求配置错误'
    }

    // 开发环境日志
    if (import.meta.env.DEV) {
      console.error('[API Error]', {
        url: error.config?.url,
        method: error.config?.method?.toUpperCase(),
        status: error.response?.status,
        message: errorResponse.message,
        error: errorResponse.error,
      })
    }

    // TODO: 可选 - 上报错误到Sentry
    // Sentry.captureException(error)

    return Promise.reject(errorResponse)
  }
)

export default client

/**
 * 便捷方法: GET请求
 */
export const get = <T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> => {
  return client.get(url, config).then(res => res.data)
}

/**
 * 便捷方法: POST请求
 */
export const post = <T = any>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return client.post(url, data, config).then(res => res.data)
}

/**
 * 便捷方法: PUT请求
 */
export const put = <T = any>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return client.put(url, data, config).then(res => res.data)
}

/**
 * 便捷方法: DELETE请求
 */
export const del = <T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> => {
  return client.delete(url, config).then(res => res.data)
}

/**
 * 便捷方法: PATCH请求
 */
export const patch = <T = any>(
  url: string,
  data?: any,
  config?: AxiosRequestConfig
): Promise<ApiResponse<T>> => {
  return client.patch(url, data, config)
}
